#include "m_led.h"
#include "STC89C5xRC.H"
#include "task.h"

#if M_LED_TASK

/* define your IO config start */
sbit MATRIX_LED_CS = P2 ^ 2; /* >! MATRIX_LED_CS */
sbit MATRIX_LED_DU = P2 ^ 0; /* >! MATRIX_LED_DU */
#define MATRIX_LED_PORT (P0) /* >! MATRIX_LED_PORT */
/* define your IO config end */

/* define your static data start */
static volatile m_led_t m_led_panel = {0x01, 0x01, 0, 0, 0};
static uint8_t code matrix_led_num_code[10][8] = {
    {0x18, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x18},  /* 0 */
    {0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C},  /* 1 */
    {0x18, 0x24, 0x04, 0x04, 0x08, 0x10, 0x20, 0x3C},  /* 2 */
    {0x1C, 0x36, 0x06, 0x0C, 0x06, 0x22, 0x36, 0x1C},  /* 3 */
    {0x00, 0x04, 0x0C, 0x14, 0x24, 0x7E, 0x04, 0x04},  /* 4 */
    {0x3C, 0x20, 0x20, 0x38, 0x04, 0x04, 0x04, 0x38},  /* 5 */
    {0x18, 0x24, 0x20, 0x38, 0x24, 0x24, 0x24, 0x18},  /* 6 */
    {0x7E, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10},  /* 7 */
    {0x18, 0x24, 0x24, 0x18, 0x24, 0x24, 0x24, 0x18},  /* 8 */
    {0x18, 0x24, 0x24, 0x1C, 0x04, 0x04, 0x24, 0x18}}; /* 9 */
/* define your static data end */

/**
 * @brief matrix_led_cs
 *
 * @param m_led_enum_t
 */
static void matrix_led_cs(m_led_enum_t status)
{
    MATRIX_LED_CS = status;
}

/**
 * @brief matrix_led_du
 *
 * @param m_led_enum_t
 */
static void matrix_led_du(m_led_enum_t status)
{
    MATRIX_LED_DU = status;
}

/**
 * @brief matrix_led_port_data
 *
 * @param port_data
 */
static void matrix_led_port_data(uint8_t port_data)
{
    MATRIX_LED_PORT = port_data;
}

/**
 * @brief matrix_set_x_port_data
 *
 * @param x_port_data
 */
void matrix_set_x_port_data(uint8_t x_port_data)
{
    MATRIX_LED_PORT = ~x_port_data;
    matrix_led_cs(SET);
    matrix_led_cs(RESET);
}

/**
 * @brief matrix_set_y_port_data
 *
 * @param y_port_data
 */
void matrix_set_y_port_data(uint8_t y_port_data)
{
    MATRIX_LED_PORT = y_port_data;
    matrix_led_du(SET);
    matrix_led_du(RESET);
}

/**
 * @brief matrix_led_blanking
 *
 */
void matrix_led_blanking(void)
{
    MATRIX_LED_PORT = 0x00;
    matrix_led_du(SET);
    matrix_led_du(RESET);
}

/**
 * @brief matrix_led_dis_num
 *
 * @param x
 * @param y
 * @param num
 * @note [按列扫描]
 *
 */
void matrix_led_dis_num(int8_t x, int8_t y, uint8_t num)
{
    uint8_t i;
    switch (num)
    {
    case 0:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[0][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 1:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[1][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 2:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[2][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 3:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[3][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 4:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[4][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 5:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[5][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 6:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[6][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 7:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[7][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 8:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[8][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    case 9:
        for (i = 0; i < 8; i++)
        {
            matrix_set_x_port_data(matrix_led_num_code[9][i]);
            matrix_set_y_port_data(0x80 >> i);
            matrix_led_blanking();
        }
        break;
    default:
        break;
    }
}

/**
 * @brief matrix_led_loop
 *
 * @param *m_led_param
 */
static void matrix_led_loop(m_led_t *m_led_param)
{

    m_led_param->matrix_tick++;
    /* matrix led loop mode_0 handle start */
    if (m_led_param->matrix_tick % 50 == 0 && m_led_param->matrix_mode == 0)
    {
        m_led_param->matrix_led_x_count = m_led_param->matrix_led_x_count << 1;
        if (m_led_param->matrix_led_x_count == 0x00)
        {
            m_led_param->matrix_led_x_count = 0x01;
            m_led_param->matrix_led_y_count = m_led_param->matrix_led_y_count << 1;
            if (m_led_param->matrix_led_y_count == 0x00)
            {
                m_led_param->matrix_led_y_count = 0x01;
                m_led_param->matrix_mode++; /* mode +1 */
            }
        }
    }
    /* matrix led loop mode_0 handle end */

    /* matrix led loop mode_1 handle start */
    if (m_led_param->matrix_tick % 500 == 0 && m_led_param->matrix_mode == 1)
    {
        m_led_param->matrix_dis_num++;
        if (m_led_param->matrix_dis_num == 10)
        {
            m_led_param->matrix_dis_num = 0;
            m_led_param->matrix_mode = 0;
        }
    }
    /* matrix led loop mode_1 handle end */

    /* matrix led dis start */
    switch (m_led_param->matrix_mode)
    {
    case 0:
        matrix_set_x_port_data(m_led_param->matrix_led_x_count);
        matrix_set_y_port_data(m_led_param->matrix_led_y_count);
        matrix_led_blanking();
        break;
    case 1:
        matrix_led_dis_num(0, 0, m_led_param->matrix_dis_num);
        break;
    default:
        break;
    }
    /* matrix led dis end */
}

/**
 * @brief matrix_led_demo
 *
 */
void matrix_led_demo(void)
{
    matrix_led_loop(&m_led_panel);
}

#endif